package com.beta.inventory.mockito;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.number.OrderingComparisons.greaterThan;
import static org.mockito.BDDMockito.willDoNothing;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.beta.inventory.PullListener;
import com.beta.inventory.SimpleInventory;


@RunWith(MockitoJUnitRunner.class)
public class SimpleInventoryBehavior {
	
	// object under test: Inventory
	@InjectMocks private SimpleInventory inventory = new SimpleInventory();
	
	// dependencies
	@Mock private PullListener listener;
	
	// Behaviors
	/**
	 * @Scenario: Inventory has one item when pull
	 * Given the inventory has one item called "Item 1"
	 * When pull Item 1 from inventory
	 * Then it has zero items
	 * And a replenish message is sent
	 * */
	@Test public void shouldPullItemByNameAndSendReplenishMessage() {
		
		// Add one item to the inventory
		inventory.addItem("Item 1", 1);
		
		// verify Item 1 existence in inventory before pull
		assertThat(inventory.itemsByName("Item 1"), is(greaterThan(0)));
		
		// pullListener will send a replenish message when we pull from the inventory
		willDoNothing().given(listener).replenish(anyString());
		
		// event under test
		inventory.pull("Item 1");
		
		// verify listener interaction
		verify(listener).replenish(anyString());
		
		// verify Item 1 existence in inventory after pull
		assertThat(inventory.itemsByName("Item 1"), is(equalTo(0)));
	}
	
	/**
	 * @Scenario: Inventory doesn't have any item when pull
	 * Given the inventory doesn't have items
	 * When pull Item 1 from inventory
	 * Then a replenish message is sent
	 * */
	@Test public void shouldSendReplenishMessage() {
		
		// verify Item 1 existence in inventory before pull
		assertThat(inventory.itemsByName("Item 1"), is(equalTo(0)));
		
		// define observer interaction
		willDoNothing().given(listener).replenish(anyString());
		
		// event under test
		inventory.pull("Item 1");
		
		// verify listener interaction
		verify(listener).replenish(anyString());
		
		// verify Item 1 existence in inventory after pull
		assertThat(inventory.itemsByName("Item 1"), is(equalTo(0)));
	}
}
